#import   "FGM.dll"
bool      SetParameters( int int_parms[], string acct_name, string log_message );
double    CheckPrices( int int_parms[], double& arr_oop[], int nof_recs, double low_value, double high_value, string log_message );
bool      OrderFromIndex( int int_parms[], int ord_count, double& dValues[] );
#import

#define ORDER_TYPE                 0
#define GRID_ORDER_SPACING         1      
#define PRICE_DIGITS               2
#define PRICE_DECIMAL_PLACES       3
#define GRID_ORDER_SPACING_STEP    4
#define ORDER_TAKE_PROFIT_PIPS     5
#define ORDER_STOP_LOSS_PIPS       6
#define LOT_SIZE_INCREASE_FIBO     7
#define LOT_SIZE_INCREASE_NONE     8
#define GRID_ORDER_INCREMENT       9
#define STANDARD_POINT             10
#define LOT_SIZE_INCREASE_AMOUNT   11
#define LOT_SIZE_INCREASE_PERCENT  12
#define LIVE_ACCOUNT_MODE          13
#define ERROR_POINTER              20

int    int_parms[15];
string log_message ="1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111";  // 100 chars

//==== Function: InitializeDLL() -- Check License for Account Name and initialize for DLL calls ====================================
bool InitializeDLL() {

  int_parms[ORDER_TYPE]                = 0;  // 9998 => special value that bypasses initial license check
  int_parms[GRID_ORDER_SPACING]        = GridOrderSpacing;
  int_parms[PRICE_DIGITS]              = Digits;
  int_parms[PRICE_DECIMAL_PLACES]      = digits;
  int_parms[GRID_ORDER_SPACING_STEP]   = GridOrderSpacingStep;
  int_parms[ORDER_TAKE_PROFIT_PIPS]    = OrderTakeProfitPips;
  int_parms[ORDER_STOP_LOSS_PIPS]      = OrderStopLossPips;
  if ( LotSizeIncreaseFibo ) 
    int_parms[LOT_SIZE_INCREASE_FIBO]  = 1;
  else
    int_parms[LOT_SIZE_INCREASE_FIBO]  = 0;
  if ( __LotSizeIncreaseNone ) 
    int_parms[LOT_SIZE_INCREASE_NONE]  = 1;
  else
    int_parms[LOT_SIZE_INCREASE_NONE]  = 0;
  int_parms[GRID_ORDER_INCREMENT]      = MathRound( GridOrderIncrement * 10000 );
  int_parms[STANDARD_POINT]            = MathRound( point * 10000 );
  int_parms[LOT_SIZE_INCREASE_AMOUNT]  = MathRound( LotSizeIncreaseAmount * 10000 );
  int_parms[LOT_SIZE_INCREASE_PERCENT] = MathRound( LotSizeIncreasePercent * 10000 );
  if ( IsDemo() )
    int_parms[LIVE_ACCOUNT_MODE]       = 0;
  else
    int_parms[LIVE_ACCOUNT_MODE]       = 1;
  
  bool ret_bool = SetParameters( int_parms, AccountName(), log_message );
/*  
  int check = GetLastError();
  if ( check == ERR_DLL_CALLS_NOT_ALLOWED || check == ERR_EXTERNAL_CALLS_NOT_ALLOWED
       || check == ERR_CANNOT_CALL_FUNCTION || check == ERR_CANNOT_LOAD_LIBRARY || check == ERROR_MOD_NOT_FOUND ) {
//  if ( check == ERR_CANNOT_LOAD_LIBRARY || check == ERR_DLL_CALLS_NOT_ALLOWED || check == ERROR_MOD_NOT_FOUND) {
    Alert( "FGM.DLL has failed to load;  Please check experts-log" );
    return( false );
  }
*/  
  if ( !ret_bool )
    Alert( log_message );
  
  return(ret_bool);
}

//==== Function: CheckOrderArray()   ====================================
double CheckOrderArray( int ord_type, int main_ord_type, double low_value, double high_value ) {
    
  // FGM_BA -- Resize array used for sorting Open and Pending trades
  if ( OrdersTotal() > ArraySize(arr_oop) - 10 ) {
    ArrayResize( arr_oop, OrdersTotal() + ORDER_ARRAY_SIZE_DELTA );
    PrintY( "Order Array has been extended -- " + ArraySize(arr_oop) ); 
  }
    
  double low_value_down = low_value - GridOrderIncrement;
  double high_value_up = high_value + GridOrderIncrement;

  int nof_recs = 0, trade, trades = OrdersTotal();
  for ( trade = 0; trade < trades; trade++ ) {
    ret_bool = OrderSelect(trade, SELECT_BY_POS, MODE_TRADES);  
    if ( !ret_bool || OrderSymbol() != Symbol() || OrderMagicNumber() != EANumber || (OrderType() != ord_type && OrderType() != main_ord_type) )
      continue;
      
    if ( ( ( ord_type == OP_BUYSTOP || ord_type == OP_SELLLIMIT ) && OrderOpenPrice() >= low_value_down )
         || ( ( ord_type == OP_SELLSTOP || ord_type == OP_BUYLIMIT ) && OrderOpenPrice() <= high_value_up ) ) {
      arr_oop[nof_recs] = OrderOpenPrice();
      nof_recs++;
    }
  }

  if ( ord_type == OP_BUYSTOP || ord_type == OP_SELLLIMIT ) 
    arr_oop[nof_recs] = low_value - GridOrderIncrement;
  else
    arr_oop[nof_recs] = low_value;
  nof_recs++;    
  if ( ord_type == OP_SELLSTOP || ord_type == OP_BUYLIMIT )
    arr_oop[nof_recs] = high_value + GridOrderIncrement;
  else
    arr_oop[nof_recs] = high_value;
  nof_recs++;    
  ArraySort( arr_oop, nof_recs );
  
  int_parms[ORDER_TYPE] = ord_type;
  
  double ret_price = CheckPrices( int_parms, arr_oop, nof_recs, low_value, high_value, log_message );
//  if ( log_message != "" )
    PrintY( log_message );
    
//  SpecialPrint( ord_type, arr_oop ); //.............
  return( ret_price );
}

//==== Function: GetOrderByIndex() ====================================
bool GetOrderByIndex( int ord_type, int ord_count, double& prc_value, double& lot_size, double& stop_loss, double& take_profit ) {

  double dValues[6];
  
  dValues[0] = CurrGridCenter;
  dValues[1] = initial_lot_size;
  dValues[2] = prc_value;
  dValues[3] = lot_size;
  dValues[4] = stop_loss;
  dValues[5] = take_profit;

  int_parms[ORDER_TYPE] = ord_type;

  bool ret_bool = OrderFromIndex( int_parms, ord_count, dValues );
  
  prc_value   = dValues[2];
  lot_size    = dValues[3];
  stop_loss   = dValues[4];
  take_profit = dValues[5];

  return( ret_bool );
}